{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 机器学习 Project2\n",
    "张逸敏 51275903084 [数据集](https://www.cs.cmu.edu/afs/cs/project/theo-11/www/naive-bayes.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-12-29T15:10:40.390132Z",
     "iopub.status.busy": "2024-12-29T15:10:40.389827Z",
     "iopub.status.idle": "2024-12-29T15:10:41.387764Z",
     "shell.execute_reply": "2024-12-29T15:10:41.386842Z",
     "shell.execute_reply.started": "2024-12-29T15:10:40.390105Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "from sklearn.datasets import fetch_20newsgroups\n",
    "from sklearn.naive_bayes import MultinomialNB, GaussianNB, BernoulliNB\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.svm import SVC\n",
    "from sklearn.pipeline import make_pipeline\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.metrics import accuracy_score, f1_score\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "from sklearn.model_selection import KFold, cross_val_predict\n",
    "import numpy as np\n",
    "import time"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 加载数据集和特征提取"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19",
    "_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5",
    "execution": {
     "iopub.execute_input": "2024-12-29T15:10:49.518044Z",
     "iopub.status.busy": "2024-12-29T15:10:49.517625Z",
     "iopub.status.idle": "2024-12-29T15:11:17.046808Z",
     "shell.execute_reply": "2024-12-29T15:11:17.045777Z",
     "shell.execute_reply.started": "2024-12-29T15:10:49.518012Z"
    },
    "trusted": true
   },
   "outputs": [],
   "source": [
    "# 加载数据集\n",
    "newsgroups = fetch_20newsgroups(subset='all')  # 使用全部数据集进行交叉验证\n",
    "\n",
    "# 特征提取\n",
    "vectorizer = TfidfVectorizer()\n",
    "vectors = vectorizer.fit_transform(newsgroups.data)  # 训练集tfidf特征"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 使用不同分类器进行5折交叉验证"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-12-29T15:11:55.194182Z",
     "iopub.status.busy": "2024-12-29T15:11:55.193842Z",
     "iopub.status.idle": "2024-12-29T15:11:58.470228Z",
     "shell.execute_reply": "2024-12-29T15:11:58.469143Z",
     "shell.execute_reply.started": "2024-12-29T15:11:55.194158Z"
    },
    "trusted": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "##### 分类器名称: MultinomialNB #####\n",
      "F1 Score: 0.8977138730486276\n",
      "Accuracy: 0.904701262867452\n",
      "5折交叉验证耗时: 1.4238409996032715 seconds\n",
      "##### 分类器名称: BernoulliNB #####\n",
      "F1 Score: 0.672221971619586\n",
      "Accuracy: 0.6986628462273161\n",
      "5折交叉验证耗时: 1.8160836696624756 seconds\n"
     ]
    }
   ],
   "source": [
    "def calculate(clf, clf_name):\n",
    "    # 5 折交叉验证\n",
    "    kf = KFold(n_splits=5, shuffle=True, random_state=42)\n",
    "    \n",
    "    # 在交叉验证中预测\n",
    "    start_time = time.time()\n",
    "    predictions = cross_val_predict(clf, vectors, newsgroups.target, cv=kf)\n",
    "    end_time = time.time()\n",
    "    \n",
    "    # 计算 F1 分数和准确率\n",
    "    f1 = f1_score(newsgroups.target, predictions, average='macro')\n",
    "    accuracy = accuracy_score(newsgroups.target, predictions)\n",
    "    \n",
    "    # 打印结果\n",
    "    print(f'##### 分类器名称: {clf_name} #####')\n",
    "    print(f'F1 Score: {f1}')\n",
    "    print(f'Accuracy: {accuracy}')\n",
    "    print(f'5折交叉验证耗时: {end_time - start_time} seconds')\n",
    "\n",
    "\n",
    "\n",
    "clf_mnb = MultinomialNB(alpha=0.1)\n",
    "clf_bnb = BernoulliNB()\n",
    "clfs = [(clf_mnb, 'MultinomialNB'), (clf_bnb, 'BernoulliNB')]\n",
    "for i in clfs:\n",
    "    calculate(i[0], i[1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 小结\n",
    "使用了朴素贝叶斯方法进行文本分类，具体来说，使用了两种版本的朴素贝叶斯。\n",
    "- MultinomialNB：F1 Score: 0.8977，Accuracy: 0.9047，交叉验证耗时1.4238s\n",
    "- BernoulliNB：F1 Score: 0.6722，Accuracy: 0.6987，交叉验证耗时: 1.8161s\n",
    "\n",
    "综上，使用 MultinomialNB 的朴素贝叶斯实现效果更好，准确率可以达到90%，且计算效率更高。"
   ]
  }
 ],
 "metadata": {
  "kaggle": {
   "accelerator": "none",
   "dataSources": [],
   "dockerImageVersionId": 30822,
   "isGpuEnabled": false,
   "isInternetEnabled": true,
   "language": "python",
   "sourceType": "notebook"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
